package com.threeti.mecool.core.application.acl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.lang.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.acls.domain.AclImpl;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.security.acls.domain.ObjectIdentityImpl;
import org.springframework.security.acls.domain.PrincipalSid;
import org.springframework.security.acls.jdbc.JdbcMutableAclService;
import org.springframework.security.acls.model.AccessControlEntry;
import org.springframework.security.acls.model.Acl;
import org.springframework.security.acls.model.NotFoundException;
import org.springframework.security.acls.model.ObjectIdentity;
import org.springframework.security.acls.model.Permission;
import org.springframework.security.acls.model.Sid;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.threeti.mecool.core.domain.model.acl.PermissionConst;
import com.threeti.mecool.core.domain.model.acl.PermissionRole;
import com.threeti.mecool.core.domain.model.acl.User;
import com.threeti.mecool.core.infrastructure.persistence.acl.PermRoleRepository;
import com.threeti.mecool.core.infrastructure.persistence.acl.UserRepository;
import com.threeti.mecool.framework.util.Lists;

//@Service
public class PermissionAclServiceImpl implements PermissionAclService {
  private static final Logger logger = LoggerFactory.getLogger(PermissionAclServiceImpl.class);
//  
//  private static final String DELETE_SID_QUERY = "DELETE FROM ACL_SID WHERE PRINCIPAL=1 AND SID=?";
//  
//  @Autowired
//  private PermRoleRepository permRoleRepo;
//  
//  @Autowired
//  private UserRepository userRepo;
//
////  @Autowired
////  private MyJdbcMutableAclService delegateAclService;
//
//  @Autowired
//  private JdbcMutableAclService delegateAclService;
//  
//  @Autowired
//  private JdbcTemplate template;
//  
//  @Override
//  @Transactional
//  public void storeCustomizedPermissionRole(PermissionRole permRole) {
//    try {
//      permRoleRepo.saveAndFlush(permRole);
//    } catch (Exception e) {
//      logger.error("保存自定义的权限角色出错,角色名可能已存在", e);
//      throw new RuntimeException(e);
//    }
//  }
//
//  @Override
//  @Transactional
//  public void createAcl(List<String[]> secureAclPairs) {
//    for (String[] securePair : secureAclPairs) {
//      int secureId = Integer.parseInt(securePair[0]); 
//      String secureType = securePair[1];
//      delegateAclService.createAcl(new ObjectIdentityImpl(secureType, secureId));
//    }
//  }
//  
//  @Override
//  @Transactional
//  public void createAcl(String[] secureIdAndTypePair) {
//    List<String[]> tmp = new ArrayList<String[]>(1);
//    tmp.add(secureIdAndTypePair);
//    createAcl(tmp);
//  }
//
//  @Override
//  @Transactional
//  public void eraseUserAclSecurityInfoAll(String userLoginName) {
//    template.update(DELETE_SID_QUERY, userLoginName);
//    
//    //TODO jay:clear cache...
//  }
//
//  @Override
//  @Transactional(propagation = Propagation.REQUIRES_NEW)
//  public void eraseUserAclSecurityInfoAllWithCache(String userLoginName, Long oldRoleIdOfUser) {
//  	PermissionRole permRole = permRoleRepo.findOneWithPermissionEntries(oldRoleIdOfUser);
//    Validate.isTrue(permRole != null && !CollectionUtils.isEmpty(permRole.getPermissionEntries()), "无法激活用户权限，未绑定任何权限角色或者该权限角色未包含任何权限操作");
//    
//    List<String> oldPermEntries = permRole.getPermissionEntries();
//  	Sid sid = new PrincipalSid(userLoginName);
//  	List<Sid> sids = Lists.newArrayList(sid);
//  	List<ObjectIdentity> objIds = Lists.newArrayList();
//  	for (String permEntry : oldPermEntries) {
//      String[] tmpEntry = permEntry.split(PermissionConst.P_MOUDLE_ID_SEPARATOR);
//      int secureId = Integer.parseInt(tmpEntry[0]);
//      String secureType = tmpEntry[1];
//      objIds.add(new ObjectIdentityImpl(secureType, secureId));
//		}
//
//	  Map<ObjectIdentity, Acl> secureMaps = delegateAclService.readAclsById(objIds, sids);
//	  if (secureMaps == null || secureMaps.size() == 0) return;
//	  
//		Set<Entry<ObjectIdentity, Acl>> secureSet = secureMaps.entrySet();
//		for (Entry<ObjectIdentity, Acl> entry : secureSet) {
//			AclImpl acl = (AclImpl)entry.getValue();
//			for (AccessControlEntry ace : acl.getEntries()) {
//				if (sid.equals(ace.getSid()))
//		  	acl.deleteAce(acl.getEntries().size()-1);
//			}
//	    //delegateAclService.updateAcl(acl, sids);//this must be call to persist the acl change
//	    delegateAclService.updateAcl(acl);//this must be call to persist the acl change
//		}
//  }
//  
//  @Override
//  @Transactional
//  public User activatePermissionsBindedWithUser(User userWithPermRoleAndPermissionsNotActivated, boolean isInsert) {
//    PermissionRole permRole = userWithPermRoleAndPermissionsNotActivated.getPermissionRole();
//    Validate.isTrue(permRole != null && !CollectionUtils.isEmpty(permRole.getPermissionEntries()), "无法激活用户权限，未绑定任何权限角色或者该权限角色未包含任何权限操作");
//    
//    List<String > permEntries = permRole.getPermissionEntries();
//    
//  	Sid sid = new PrincipalSid(userWithPermRoleAndPermissionsNotActivated.getLoginName());
//  	List<Sid> sids = Lists.newArrayList(sid);
//    
//    for (String permEntry : permEntries) {
//      String[] tmpEntry = permEntry.split(PermissionConst.P_MOUDLE_ID_SEPARATOR);
//      int secureId = Integer.parseInt(tmpEntry[0]);
//      String secureType = tmpEntry[1];
//      int permissionMask = Integer.parseInt(tmpEntry[2]);
//      switch (permissionMask) {
//        case PermissionConst.P_ADMIN_MASK:
//        	if (isInsert)
//        		grantPermissionWhenInsert(userWithPermRoleAndPermissionsNotActivated.getLoginName(), BasePermission.ADMINISTRATION, secureId, secureType);
//        	else
//            grantPermission(userWithPermRoleAndPermissionsNotActivated.getLoginName(), BasePermission.ADMINISTRATION, secureId, secureType, sids);
//          break;
//        case PermissionConst.P_READ_MASK:
//        	if (isInsert)
//        		grantPermissionWhenInsert(userWithPermRoleAndPermissionsNotActivated.getLoginName(), BasePermission.READ, secureId, secureType);
//        	else
//            grantPermission(userWithPermRoleAndPermissionsNotActivated.getLoginName(), BasePermission.READ, secureId, secureType, sids);
//          break;
//        case PermissionConst.P_CREATE_MASK:
//        	if (isInsert)
//        		grantPermissionWhenInsert(userWithPermRoleAndPermissionsNotActivated.getLoginName(), BasePermission.CREATE, secureId, secureType);
//        	else
//            grantPermission(userWithPermRoleAndPermissionsNotActivated.getLoginName(), BasePermission.CREATE, secureId, secureType, sids);
//          break;
//        case PermissionConst.P_WRITE_MASK:
//        	if (isInsert)
//        		grantPermissionWhenInsert(userWithPermRoleAndPermissionsNotActivated.getLoginName(), BasePermission.WRITE, secureId, secureType);
//        	else
//            grantPermission(userWithPermRoleAndPermissionsNotActivated.getLoginName(), BasePermission.WRITE, secureId, secureType, sids);
//          break;
//        case PermissionConst.P_DELETE_MASK:
//        	if (isInsert)
//        		grantPermissionWhenInsert(userWithPermRoleAndPermissionsNotActivated.getLoginName(), BasePermission.DELETE, secureId, secureType);
//        	else
//            grantPermission(userWithPermRoleAndPermissionsNotActivated.getLoginName(), BasePermission.DELETE, secureId, secureType, sids);
//          break;
//        default:
//          throw new RuntimeException("ACL绑定未指定任何权限");
//      }
//    }
//    
//    return userRepo.saveAndFlush(userWithPermRoleAndPermissionsNotActivated);
//  }
//  
//  @Override
//  @Transactional
//  public void renewAllTheAclsRelatedByPermissionRole(PermissionRole tryingDetachedPermRole) {
//  	
//	  List<User> targetUsers = userRepo.findByPermissionRoleId(tryingDetachedPermRole.getId());
//
//    for (User user : targetUsers) {
//    	//do renew
//    	eraseUserAclSecurityInfoAllWithCache(user.getLoginName(), tryingDetachedPermRole.getId());
//    	
//    	user.setPermissionRole(tryingDetachedPermRole);
//      activatePermissionsBindedWithUser(user, false);
//		}
//  	
//  	tryingDetachedPermRole = permRoleRepo.save(tryingDetachedPermRole);
//  }
//  
//  //@Override
//  @Transactional
//  public void renewAclsRelatedByPermissionRole(User userWithNewPermissionRoleAndEntries, Long oldRoleIdOfUser) {
//  	
//	  //List<User> targetUsers = userRepo.findByPermissionRoleId(tryingDetachedPermRole.getId());
//
//    //for (User user : targetUsers) {
//    	//do renew
//    	eraseUserAclSecurityInfoAllWithCache(userWithNewPermissionRoleAndEntries.getLoginName(), oldRoleIdOfUser);
//    	
//    	//user.setPermissionRole(tryingDetachedPermRole);
//      activatePermissionsBindedWithUser(userWithNewPermissionRoleAndEntries, false);
//		//}
//  	
//  	//tryingDetachedPermRole = permRoleRepo.save(tryingDetachedPermRole);
//  }
//  
//  @Override
//  @Transactional
//  public void renewAllTheAclsRelatedByPermissionRole(Long tryingExistPermRoleId) {
//	  List<User> targetUsers = userRepo.findByPermissionRoleId(tryingExistPermRoleId);
//
//    for (User user : targetUsers) {
//    	//do renew
//    	eraseUserAclSecurityInfoAllWithCache(user.getLoginName(), tryingExistPermRoleId);
//      activatePermissionsBindedWithUser(user, false);
//		}
//  }
//
//  private void grantPermissionWhenInsert(String userLoginName, Permission permission,int secureId, String secureType) {
//    ObjectIdentity objId = new ObjectIdentityImpl(secureType, secureId);
//
//    AclImpl acl;
//    try {
//      acl = (AclImpl) delegateAclService.readAclById(objId);
//    } catch (NotFoundException e) {
//      String msg;
//      logger.error(msg = "系统未提供内置权限," + objId, e);
//      throw new RuntimeException(msg);
//    }
//
//    acl.insertAce(acl.getEntries().size(), permission, new PrincipalSid(userLoginName), true);//at the last position
//    delegateAclService.updateAcl(acl);
//  }
//
//  private void grantPermission(String userLoginName, Permission permission,int secureId, String secureType,List<Sid> sids) {
//    ObjectIdentity objId = new ObjectIdentityImpl(secureType, secureId);
//
//    AclImpl acl;
//    try {
//      acl = (AclImpl) delegateAclService.readAclById(objId);
//    } catch (NotFoundException e) {
//      String msg;
//      logger.error(msg = "系统未提供内置权限," + objId, e);
//      throw new RuntimeException(msg);
//    }
//
//    acl.insertAce(acl.getEntries().size(), permission, new PrincipalSid(userLoginName), true);//at the last position
//    delegateAclService.updateAcl(acl);
//  }
}
